iT邦幫忙

2024 iThome 鐵人賽

DAY 18
0
自我挑戰組

前端工程師的java學習紀錄系列 第 18

Day18-繼承 & override & super

  • 分享至 

  • xImage
  •  

繼承

從某個class 繼承屬性 方法 等直接使用,不用另外宣告。

被繼承的類稱為superclass
繼承的類稱為subclass

下面統一會以這兩個英文作為代稱。

格式:

subclass extends superclass {}
public Person {
	String name;
	int age;
	
	public String getInfo() {
		return "name is = " + name + ", age is = " + age);
	}
}

public Student extends Person {
	String school;
}

可以從兩種方式進行繼承的設計:

  • 由上到下(例如上面是先定義了Person 接著從Person 中找到有關聯可以被繼承的部分後,接著再定義Student )。
  • 由下到上(例如先定義了冷氣、電風扇、洗衣機等各種電器,從中找到可以繼承的部分,如耗電量、廠牌等等,再定義一個電器的,讓這些這些電器可以繼承)。

繼承的好處:

  • 減少重複的程式碼,提高復用性
  • 更易於擴展
  • 多態的前提
💡在使用繼承時可以使用"is-a"的方式去思考符不符合繼承的關係
💡不要為了為了繼承而繼承
💡例如狗和貓都很多共同的屬性,就讓貓成為狗的superclass

superclass屬性方法使用private 進行封裝時,subclass也是會一併繼承這些屬性方法 ,但是沒有權限使用。

superclass可以被多個subclass``繼承、但是一個類只能有一個superclass,一個類繼承另一個類以後,它還可以被其他的類繼承。

這樣是可以的:

public A {}
public B extends A {}
public C extends B {}

這樣是不可以的:

public A {}
public B {}
public C extends A , B {}

https://ithelp.ithome.com.tw/upload/images/20241002/20139160pvx9OO405o.jpg

一個類只能有一個super class無法同時繼承多個class,但是可以多層的繼承。
例如:

  • G -> F -> D -> A的關係就是多層的繼承。
  • D -> B 是無法多個繼承。(D已經繼承A的情況下,就無法再繼承B)

封裝權限 private default protected public 中的protected 權限是公開到subClass

public Person {
	String name;
	int age;
	protected String phone;
	
	public String getInfo() {
		return "name is = " + name + ", age is = " + age);
	}
}

public Student extends Person {
	String school;
}

// 假設在不同的package中
import com.person.Person
public StudentTest {
	public static void main(String[] args) {
		Student student1 = new Student();
		
		student1.phone = "0912345678";
		
		
		Person person = new Person();
		
		// 無法使用
		person.phone = "0998765432";
	}
}

由於StudentTest並不是Personsubclass,且也不在同一個package 中,所以它沒有辦法使用Person 中宣告為protectedphone 屬性


重寫override

override指的是當subclass將從superclass``繼承方法中的程式碼進行重寫。

例如:

public Person {
	String name;
	int age;
	protected String phone;
	
	public String getInfo() {
		return "name is = " + name + ", age is = " + age);
	}
}

public Student extends Person {
	String school;
	
	public String getInfo() {
		return "這是被重寫過的getInfo method";
	}
}

若是繼承的方法有overload時,只要參數的內容相同即可只重寫那一個方法,其餘的一樣會繼承

有幾個需要注意的部分:

  1. 權限修飾符:重寫方法的權限修飾符不能小於superclass``方法的權限修飾符。

例如:💡這樣是錯誤的無法重寫

public Person {
	String name;
	int age;
	protected String phone;
	
	protected String getInfo() {
		return "name is = " + name + ", age is = " + age);
	}
}

public Student extends Person {
	String school;
	
	String getInfo() {
		return "這是被重寫過的getInfo method";
	}
}

protected 的權限相對於default(沒有寫任何權限) 的權限還大,這樣是無法重寫的。

權限由小到大:

private (只有自身可以使用)→ default (相同package 可以使用)→ protected (繼承subclass可以使用) → public (任何都可以使用)

  1. 返回的數據類型:
  • void:必須也是void
  • 基本數據類型:必須跟superclass相同。(即便可以提昇也不能)
  • 引用類型:該類型必須至少是superclass返回類型的subclass,或與superclass相同。

基本數據類型:

public Person {
	int age;

	public int getAge() {
		return age;
	}}

public Student extends Person {
	// 這樣不行
	/*
	public double getAge() {
		return age;
	}
	*/
	//這樣可以
	public int getAge() {
		age += 5
		return age;
	}
}

引用數據類型:

// Person class
public Person {
	
	public Person getPerson() {
	}
}

// Student class
public Student extends Person {
	
	public Student getPerson() {
	}
}
  1. 異常類型(後續會提到):跟返回數據類型的引用數據類型一樣,只可以是superclass異常類型的subclass或相同。

super

super指的是當繼承了superclass屬性方法時,還是需要使用superclass屬性方法,可以使用super去改成調用superclass屬性方法,但是使用super時還是會受到權限的限制。

例如:

public Person {
	String name;
	int age = 20;
	protected String phone;
	
	public String getInfo() {
		return "name is = " + name + ", age is = " + age);
	}
}

public Student extends Person {
	int age = 10;
	String school;
	
	
	public void printAge() {
		System.out.println(age); // 10
		System.out.println(super.age); // 20
	}
	
	public String getInfo() {
		super.getInfo();
		return "這是被重寫過的getInfo method";
	}
}

當在屬性方法前面加上super. 時,會直接去superclass找符合的屬性方法

若是在構造器中使用時,super 必須放在構造器中的第一行(跟this)一樣,並且thissuper 只能擇一使用。

public Person {
	String name;
	int age = 20;
	
	public Person() {
	
	}
	
	public Person(String name, int age) {
		this .name = name;
		this.age = age;	
	}
}

public Student extends Person {
	int age = 10;
	String school;
	
	public Student() {
		super();
	}
	
	public Student(String name, int age) {
		super(name, age);
	}
	
}

subclass構造器 中,一定會有其中一個是使用super 去調用superclass構造器


上一篇
Day17-constructor & this
下一篇
Day19-多態性
系列文
前端工程師的java學習紀錄38
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言